package itsm.isperp.module.controller.app;

import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.Queue;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.perf4j.log4j.GraphingStatisticsAppender;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

/**
 * 
 * 
 * @author lizx
 * @date 2013-1-21
 * @version V1.0
 */
@Controller
@RequestMapping("/app/statistics")
public class StatisticsController {

	private static final int NUMBER_OF_MILLISECONDS_IN_A_DAY = 86400000;

	private static final int NUMBER_OF_MILLISECONDS_IN_AN_HOUR = 3600000;

	private static final int NUMBER_OF_MILLISECONDS_IN_A_MINUTE = 60000;

	private static final int NUMBER_OF_MILLISECONDS_IN_A_SECOND = 1000;

	private final Date upTimeStartDate = new Date();

	@RequestMapping(value = "", method = RequestMethod.GET)
	protected ModelAndView handleRequestInternal(
			final HttpServletRequest httpServletRequest,
			final HttpServletResponse httpServletResponse) throws Exception {
		final ModelAndView modelAndView = new ModelAndView("viewStatisticsView");
		modelAndView.addObject("startTime", this.upTimeStartDate);
		final double difference = System.currentTimeMillis()
				- this.upTimeStartDate.getTime();

		modelAndView.addObject(
				"upTime",
				calculateUptime(
						difference,
						new LinkedList<Integer>(Arrays.asList(
								NUMBER_OF_MILLISECONDS_IN_A_DAY,
								NUMBER_OF_MILLISECONDS_IN_AN_HOUR,
								NUMBER_OF_MILLISECONDS_IN_A_MINUTE,
								NUMBER_OF_MILLISECONDS_IN_A_SECOND, 1)),
						new LinkedList<String>(Arrays.asList("day", "hour",
								"minute", "second", "millisecond"))));
		modelAndView.addObject("totalMemory", Runtime.getRuntime()
				.totalMemory() / 1024 / 1024);
		modelAndView.addObject("maxMemory",
				Runtime.getRuntime().maxMemory() / 1024 / 1024);
		modelAndView.addObject("freeMemory",
				Runtime.getRuntime().freeMemory() / 1024 / 1024);
		modelAndView.addObject("availableProcessors", Runtime.getRuntime()
				.availableProcessors());
		modelAndView.addObject("serverHostName",
				httpServletRequest.getServerName());
		modelAndView.addObject("serverIpAddress",
				httpServletRequest.getLocalAddr());

		final Collection<GraphingStatisticsAppender> appenders = GraphingStatisticsAppender
				.getAllGraphingStatisticsAppenders();

		modelAndView.addObject("pageTitle", modelAndView.getViewName());
		modelAndView.addObject("graphingStatisticAppenders", appenders);
		modelAndView.setViewName("app/statistics");
		return modelAndView;
	}

	protected String calculateUptime(final double difference,
			final Queue<Integer> calculations, final Queue<String> labels) {
		if (calculations.isEmpty()) {
			return "";
		}

		final int value = calculations.remove();
		final double time = Math.floor(difference / value);
		final double newDifference = difference - (time * value);
		final String currentLabel = labels.remove();
		final String label = time == 0 || time > 1 ? currentLabel + "s"
				: currentLabel;

		return Integer.toString(new Double(time).intValue()) + " " + label
				+ " " + calculateUptime(newDifference, calculations, labels);

	}
}
